package com.tzt.controller.app;

import com.alibaba.fastjson.JSON;
import com.tzt.common.BaseController;
import com.tzt.contents.Constantpool;
import com.tzt.dao.DictMapper;
import com.tzt.dao.OrderMapper;
import com.tzt.entity.BaseResult;
import com.tzt.entity.OrderEntity;
import com.tzt.util.GetCacheUtil;
import com.tzt.util.NomalUtil;
import com.tzt.util.PayCommonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

@RestController
public class WxpayController extends BaseController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    private OrderMapper orderMapper;
    @Value("${wxpay.appid}")
    public String appid;
    @Value("${wxpay.mchid}")
    public String mchid;
    @Value("${wxpay.key}")
    public String key;
    @Value("${wxpay.httpconnecttimeoutms}")
    public int httpconnecttimeoutms;
    @Value("${wxpay.httpreadtimeoutms}")
    public int httpreadtimeoutms;
    @Value("${wxpay.cu}")
    public String cu;
    @Value("${wxpay.tradetype}")
    public String tradetype;
    @Value("${wxpay.appurl}")
    public String appurl;
    @Autowired
    private GetCacheUtil getCacheUtil;
    @Resource
    private DictMapper dictMapper;

    @RequestMapping(value = "/api/unifiedOrder", method = RequestMethod.POST)
    public BaseResult unifiedOrder(HttpServletRequest request) {
//        String path = Class.class.getClass().getResource("/").getPath();
        Map<String, String[]> reqMap = request.getParameterMap();
        BaseResult baseResult = new BaseResult();
        String[] s1 = reqMap.get("body");
        String[] s2 = reqMap.get("out_trade_no");
        String[] s3 = reqMap.get("total_fee");
        String[] s4 = reqMap.get("product_id");
        String[] s5 = reqMap.get("fee_type");
        String[] s6 = reqMap.get("product_num");
        if (!(s1 != null && s1.length > 0) || !(s2 != null && s2.length > 0) || !(s3 != null && s3.length > 0) || !(s4 != null && s4.length > 0) || !(s6 != null && s6.length > 0)) {
            baseResult.setState(-998);
            baseResult.setMsg("parameter empty");
            baseResult.setSuccess(false);
            return baseResult;
        }
        if (NomalUtil.isNull(s1[0]) || NomalUtil.isNull(s2[0]) || NomalUtil.isNull(s3[0]) || NomalUtil.isNull(s4[0]) || NomalUtil.isNull(s6[0])) {
            baseResult.setState(-998);
            baseResult.setMsg("parameter empty");
            baseResult.setSuccess(false);
            return baseResult;
        }
        try {
            if (Double.valueOf(s3[0]) <= 0) // 防止抓包修改订单金额造成损失
            {
                baseResult.setState(-997);
                baseResult.setMsg("total_fee error");
                baseResult.setSuccess(false);
                return baseResult;
            }
        } catch (Exception e) {
            e.printStackTrace();
            baseResult.setState(-996);
            baseResult.setMsg("total_fee format error");
            baseResult.setSuccess(false);
            logger.error(e.getMessage());
            return baseResult;
        }
        Map<String, String> data = new HashMap<String, String>();
        data.put("body", s1[0]);
        data.put("out_trade_no", s2[0]);
        data.put("total_fee", s3[0]);
        data.put("product_id", s4[0]);
        data.put("spbill_create_ip", request.getRemoteAddr());
        if (s5 != null && s5.length > 0) {
            data.put("fee_type", s5[0]);
        }
        data.put("product_num", s6[0]);
        try {
            return getWXPay(data);
        } catch (Exception e) {
            e.printStackTrace();
            baseResult.setState(-999);
            baseResult.setMsg("system error");
            baseResult.setSuccess(false);
            logger.error(e.getMessage());
            return baseResult;
        }
    }

    /**
     * 微信支付回调接口
     * 遗留问题-验签未过
     * @param request
     * @return
     */
    @RequestMapping(value = "/api/wxNotify", method = RequestMethod.POST)
    public Map<String, Object> wxNotify(HttpServletRequest request) {
        Map<String, String[]> packageParams = request.getParameterMap();
        // 判断签名是否正确
//        String resXml;
//        if (PayCommonUtil.isTenpaySign("UTF-8", packageParams))
//        {
            if ("SUCCESS".equals(packageParams.get("return_code")[0]))
            {
                // 如果返回成功
                String mch_id = packageParams.get("mch_id")[0]; // 商户号
                String out_trade_no = packageParams.get("out_trade_no")[0]; // 商户订单号
                String total_fee = packageParams.get("total_fee")[0];
                String transaction_id = packageParams.get("transaction_id")[0];
                if(NomalUtil.isNull(out_trade_no)){
                    return paramFailedMessage();
                }
                logger.info("订单查找out_trade_no："+out_trade_no);
                // 根据订单号查订单
                OrderEntity order = orderMapper.getOrderInfoByOrderId(out_trade_no);
                if (order == null) {
                    return paramFailedMessage();
                }
                // 验证商户ID 和 价格以防止篡改金额
                if (mchid.equals(mch_id) && order != null && order.getOrderAmount().multiply(new BigDecimal(100)).compareTo(new BigDecimal(total_fee.trim())) == 0)
                {
                    OrderEntity orderEntity = new OrderEntity();
                    orderEntity.setTradeNo(transaction_id);
                    orderEntity.setStatus(0);
                    orderEntity.setOrderNumber(out_trade_no);
                    orderEntity.setPaymentTime(new Date());
                    orderEntity.setPayType("weixin");
                    orderMapper.updatePayStatus(orderEntity);
                    return successData(new HashMap<String, Object>());
                } else {
                    return paramFailedMessage();
                }
            } else {// 如果微信返回支付失败，将错误信息返回给微信
                return failedData(new HashMap<String, Object>(), "1", "交易失败");
            }
//        } else {
//            return failedData(new HashMap<String, Object>(), "1", "通知签名验证失败");
//        }
    }

    /**
     * 创建微信交易对象
     */
    public SortedMap<Object, Object> getWXPrePayID() {
        SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
        parameters.put("appid", appid);
        parameters.put("mch_id", mchid);
        parameters.put("nonce_str", PayCommonUtil.CreateNoncestr());
        parameters.put("fee_type", cu);
        String notifyUrl = getCacheUtil.getDictValueByKey(Constantpool.DICT_SERVICE_DOMAIN_NAME) + getCacheUtil.getDictValueByKey(Constantpool.DICT_WX_NOTIFY_URL);
        parameters.put("notify_url", notifyUrl);
        parameters.put("trade_type", tradetype);
        return parameters;
    }

    /**
     * 自定义创建微信预付单
     * @param data
     * @return
     */
    public BaseResult getWXPay(Map<String, String> data) {
        BaseResult baseResult = new BaseResult();
        try {
            SortedMap<Object, Object> parameters = getWXPrePayID(); // 获取预付单，此处已做封装，需要工具类
            parameters.put("body", data.get("body"));
            parameters.put("spbill_create_ip", data.get("spbill_create_ip"));
//            parameters.put("out_trade_no", data.get("out_trade_no") + "APP");
            parameters.put("out_trade_no", data.get("out_trade_no"));
            // parameters.put("total_fee", data.get("total_fee")); // 测试时，每次支付一分钱，微信支付所传的金额是以分为单位的，因此实际开发中需要x100
            parameters.put("total_fee", new BigDecimal(data.get("total_fee")).multiply(new BigDecimal(100)).intValue()+""); // 上线后，将代码放开
            // 设置签名
            String sign = PayCommonUtil.createSign("UTF-8", parameters);
            parameters.put("sign", sign);
            // 封装请求参数结束
            String requestXML = PayCommonUtil.getRequestXml(parameters); // 获取xml结果
            logger.info("封装请求参数是：" + requestXML);
            // 调用统一下单接口
            String result = PayCommonUtil.httpsRequest(appurl, "POST", requestXML);
            logger.info("调用统一下单接口：" + result);
            SortedMap<Object, Object> parMap = PayCommonUtil.startWXPay(result);
            logger.info("最终的map是：" + parMap.toString());
            baseResult.setWxPayOrderStr(JSON.toJSONString(parMap));
            baseResult.setState(1);
            baseResult.setMsg("ok");
            baseResult.setSuccess(true);
        } catch (Exception e) {
            baseResult.setState(-999);
            baseResult.setMsg("wxpay error");
            baseResult.setSuccess(false);
            e.printStackTrace();
            logger.error(e.getMessage());
        }
        return baseResult;
    }

}
